<?php
namespace control;
/*
*生产入库单类
*/

class machiningInOrderClass extends adIndexClass
{
    private const page = 'machiningInOrder';
    private const table = 'machining_in_order';
    private const tableMx = 'machining_in_order_detail';
    private const title = '生产入库单';

    /**
     * 字段初始化
     */
    public function fieldInit($fun): array
    {
        switch ($fun) {
            default:
                $tr = [
                    'orderNo'          => [
                        'name'  => "单据编号",
                        'width' => 250,
                        'sort' => 1,
                    ],
                    'line'  => [
                        'name'  => '生产线',
                        'width' => 300,
                    ],
                    'manager'         => [
                        'name'  => '经手人',
                        'width' => 250,
                    ],
                    'num'          => [
                        'name'  => '数量',
                        'width' => 250,
                    ],
                    'recordDate'          => [
                        'name'  => '单据日期',
                        'width' => 250,
                        'sort' => 1,
                    ],
                    'state'          => [
                        'name'  => '状态',
                        'width' => 200,
                    ]
                ];
        }
        return $tr;
    }

    /*列表页-查询条件*/
    public function homeOptions($isAsync = true)
    {
        //生成查询表单
        $html = $this->tableShow([
            [
                [
                    "单据编号" => text(array("name" => "orderNo")),
                    "生产线"   => selectMultiple(["name" => "lineId", 'table' => "product_line", 'sqlId' => 'id', 'where' => "coid = '" . self::$coid . "'", 'sqlField' => 'name']),
                    '经手人' => selectMultiple(["name" => "manager", 'table' => "staff", 'sqlId' => 'stid', 'sqlField' => 'name']),
                ],
                [
                    "单据日期" => text(array("name" => "createTime", 'laydate' => ['type' => 'date', 'range' => '~'])),
                    "状态" => select(["name" => "state", 'option' => ['草稿', '待确认', '已确认']]),
                ]
            ]
        ],1);
        //返回
        if (!$isAsync) {
            return $html;
        } else {
            return json_encode(['html' => $html], 320);
        }
    }

    /*列表-查询条件*/
    public function home()
    {
        $html = $this->homeOptions(false);
        //控件
        $button = "";
        $url = root . "control/adIndex.html?cla=" . self::page;
        if ($this->power(self::page, "edit")) {
            $button .= "<span onclick=\"newIframe('" . self::title . "详情','" . $url . "&fun=edit')\" class='spanButton'>新增</span>\n";
        }

        if ($this->power(self::page, "del")) {
            $button .= "<span class='spanButton' onclick=\"layer('{$this->get('cla')}', 'operate', {'act': 'del'})\">删除</span>\n";
        }
        if ($this->power(self::page, "confirm")) {
            $button .= "<span onclick=\"layer('" . self::page . "','batchConfirm',$('form[name=listForm]').serialize())\" class='spanButton'>批量确认</span>";
        }
        //返回
        return $this->homeFun($this->search($html, layout: 'pop', toolButton: $button));
    }

    /*客户列表-查询结果*/
    public function homeSearch()
    {
        //like查询数组
        $like = array(
            "orderNo" => $this->post('orderNo'),
        );
        //全等查询数组
        $equal = array(
            'lineId' => $this->post('lineId'),
            "state" => $this->post('state'),
            "manager" => $this->post('manager'),
            'coid' => self::$coid
        );
        $and = "";
        if ($this->post('createTime')) {
            $and .= self::timeComparison($this->post('createTime'), 'date', 'recordDate');
        }
        //排序
        $orderBy = $this->listSort(array(
            "search"  => $this->post('list_sort_key') ?: 'recordDate desc,time',
            "sort" => $this->post('list_sort') ?: "desc",
            "array"   => array(),
        ));
        //获取查询结果
        $where = search(array("like" => $like, "=" => $equal)) . $and;
        $page = $this->page(array("table" => self::table, "where" => $where, "order" => $orderBy['orderBy']));
        //获取自定义字段参数
        $installSearch = $this->installSearch();
        $body          = [];
        //表格控件区
        $liButton = array(
            $this->checkAll("listForm", "listId")
        );
        //获取记录
        $url = root . "control/adIndex.html?cla=" . self::page;
        foreach ($page['array'] as $array) {
            //列表控件
            $dominate = array(
                "box" => array("name" => "listId", "value" => $array['id']),
                "edit" => array("title" => "编辑", "click" => "newIframe('" . self::title . "详情','" . $url . "&fun=edit&id=" . $array['id'] . "')"),
                "detail" => array("title" => self::title . "详情", "click" => "newIframe('" . self::title . "详情','" . $url . "&fun=detail&id=" . $array['id'] . "')"),
                'track' => array("title" => "单据追踪", "click" => "newIframe('单据追踪','" . root . "control/adIndex.html?cla=orderTrack&fun=home&orderType=生产入库单&id=" . $array['id'] . "')"),
            );
            if ($array['state'] == '已确认') {
                unset($dominate['edit']);
            }
            $liButton[] = $this->dominate($dominate);
            //本行初始化
            $row = [];
            foreach ($installSearch['key'] as $key) {
                switch ($key) {
                    case 'line':
                        $line = query('product_line', "id = '$array[lineId]'");
                        $row[] = $line['workshop'] . '-' . $line['name'];
                        break;
                    case 'num':
                        $num = find(array('table' => self::tableMx, 'where' => "orderId = '$array[id]'", 'sum' => "num"));
                        $row[] = self::lostZero($num, 'numPrecision');
                        break;
                    case 'manager':
                        $row[] = self::findStaff($array['manager']);
                        break;
                    default:
                        $row[] = isset($array[$key]) && $array[$key] ? $array[$key] : '';
                }
            }
            $body[] = $row;
        }
        $totalQuery = find([
            'table'  => self::tableMx,
            'single' => " orderId in (select id from ".self::table." where 1=1 {$where}) ",
            'field'  => "ifnull(sum(num),0) as num",
        ]);
        $total    = [
            'num'        => self::lostZero($totalQuery['num'], 'numPrecision'),
        ];
        //生成页面
        $li = $this->li(array(
            "body" => $body,
            "install" => $installSearch,
            "button" => array("html" => $liButton),
            "orderBySign" => $orderBy,
            "page" => $page['para'],
            "total"       => $total,
        ));
        //返回
        $json['html'] = $page['hint'] . "<form name='listForm'>" . $li . "</form>" . $page['button'] . clear;
        return json_encode($json, 320);
    }

    public function batchConfirm()
    {
        $listArr = $this->post('listId');
        if (self::isNull($listArr)) {
            return json_encode(["warn" => "请选择一条数据"], 320);
        }
        $detailArr = find([
            'table' => " machining_in_order_detail as b left join  machining_in_order as a on a.id = b.orderId ",
            "field" => " a.recordDate,a.orderNo,b.*",
            "where" => " a.id in ('" . implode("','", $listArr) . "') and a.state='草稿' order by a.recordDate desc,a.time desc,list"
        ]);
        $result = find(array('table' => 'warehouse', 'where' => "coid = '" . self::$coid . "' and state = '启用' order by time desc"));

        $li = '';

        if (is_array($result['array'])) {
            foreach ($result['array'] as $array) {
                $li .= "<li data-id='$array[id]'>{$array['name']}</li>";
            }
        }
        if (empty($li)) {
            $li = "<li>未找到仓库</li>";
        }
        $tr[] = ['单据编号', '单据日期', '存货类别', '物料编码', '物料名称', '规格型号', '单位', "<div class='warehouse'>仓库&emsp;<span class='del-row-button' id='chooseWareHouse'>批量</span><div class='stateBlock'><ul>{$li}</ul></div></div>", '数量','批次', '源单类别', '关联单号', '备注'];
        foreach ($detailArr['array'] as $detail) {
            $material = query('material', " id = '$detail[materialId]'");
            $unitOption = machiningOrderClass::unitOption($material['id']);
            $machiningOrderMx = query('machining_order_mx', "id = '$detail[sourceId]'");
            $machiningOrder = query('machining_order', "id = '$machiningOrderMx[orderId]'");

            $tr[] = [
                hidden(['name' => "listId[]", "value" => $detail['id']]) .
                $detail['orderNo'],
                $detail['recordDate'],
                $material['subject'],
                $material['code'],
                $material['name'],
                $material['model'],
                select(array('name' => 'unitDetail[]', 'data' => ['unit' => $detail['unit']], 'change' => 'unitChange', 'option' => $unitOption, 'title' => '单位', 'value' => $detail['unit'])),
                idSelect(array('name' => 'warehouseId[]', 'sqlForm' => "warehouse where coid = '" . self::$coid . "' and state = '启用' order by time desc", 'sqlId' => 'id', 'sqlField' => "name", 'title' => '仓库', 'value' => $detail['warehouseId'])),
                text(array('name' => 'num[]', 'type' => 'number', 'value' => floatval($detail['num']))),
                text(array('name' => 'batch[]', 'value' => $detail['batch'])),
                self::orderType($machiningOrder['orderType']),
                $machiningOrder['orderNo'],
                text(array('name' => 'mxText[]', 'value' => $detail['text'])),
            ];
        }
        //生成表单
        $html = $this->layerEdit(array("table" => array(
            array(
                "<div style='overflow: auto'>".$this->tableMany(array('tr' => $tr))."</div>"
            ),
        )));
        $html .= <<<EOF
<script>
//点击非下拉区域隐藏
$(document).bind('click', function (e) {
    let target = $(".stateBlock");
    let obj = $(".warehouse");
    if(!target.is(e.target) && target.has(e.target).length ===0 && !obj.is(e.target) && obj.has(e.target).length ===0){
      target.hide();
    }
});
$("#chooseWareHouse").on('click',function() {
   $(".stateBlock").show();
})
$(".warehouse .stateBlock li").on('click',function() {
    let id = $(this).data('id');
    $("select[name='warehouseId[]']").val(id);
   $(".stateBlock").hide();
})


</script>
EOF;

        //返回
        return $this->layer(array("title" => "批量确认", "height" => 700, "width" => 1000, "html" => $html));
    }

    /**
     * 确认
     */
    public function batchConfirmEdit()
    {
        $listIdArr = $this->post('listId');
        $unitDetailArr = $this->post('unitDetail') ?: [];
        $warehouseIdArr = $this->post('warehouseId') ?: [];
        $numArr = $this->post('num') ?: [];
        $batchArr = $this->post('batch') ?: [];
        $mxTextArr = $this->post('mxText') ?: [];

        if (self::is_null_array($unitDetailArr)) {
            $json['warn'] = "请选择单位";
            goto resp;
        } elseif (self::is_null_array($warehouseIdArr)) {
            $json['warn'] = "请选择仓库";
            goto resp;
        } elseif (self::is_null_array($numArr)) {
            $json['warn'] = "请填写数量";
            goto resp;
        } else {
            foreach ($listIdArr as $k => $listId) {
                $json['warn'] = self::update([
                    "table" => self::tableMx,
                    "field" => [
                        'num'         => $numArr[$k],
                        'unit'        => $unitDetailArr[$k],
                        'warehouseId' => $warehouseIdArr[$k],
                        'text'        => $mxTextArr[$k],
                        'batch'        => $batchArr[$k],
                    ],
                    "where" => " id = '$listId'"
                ]);
                if ($json['warn'] != "更新成功") {
                    goto resp;
                }
            }
        }
        $field = [
            'state'       => '已确认',
            'checkId'     => self::$stid,
            'confirmTime' => $this->time
        ];

        if (!$this->power(self::page, 'confirm')) {
            $json['warn'] = '你还没有确认权限';
        } else {
            $this->startTrans();
            $infoArr = find([
                'table' => self::table,
                "where" => "id in (select distinct orderId from " . self::tableMx . "  where id in ('" . implode("','", $listIdArr) . "')) and state='草稿'"
            ]);
            $id = "";
            $bool = '未生成入库单';
            $json['warn'] = '未找到主表';
            foreach ($infoArr['array'] as $info) {
                $id .= " [{$info['id']}] ";
                $json['warn'] = update(array(
                    "table" => self::table,
                    "field" => $field,
                    "where" => "id = '$info[id]'",
                ));
                //生成入库单和质检单
                $bool = $this->insertInventory($info);
                if (!$bool) {
                    $json['warn'] = "生成入库单失败";
                    $this->rollback();
                    goto resp;
                }
                self::insertOperateLog($info['id'],self::title,"确认");
            }

            if (in_array($json['warn'], ["新增成功", "更新成功"]) && $bool === true) {
                $this->commitTrans();
                //添加日志
                $type = mb_substr($json['warn'], 0, 2, 'utf-8');
                $text = $this->control['name'] . $type . "了" . self::title . " " . $id ;
                $this->logText(["type" => self::page, "text" => $text]);
                //返回
                $_SESSION['warn'] = $json['warn'];
                $json['warn'] = 2;
            } else {
                $json['warn'] = $json['warn'] == '更新成功' ? $bool : $json['warn'];
                $this->rollback();
            }

        }
        resp:
        return json_encode($json, 320);
    }





    public static function orderType($orderType, $isNull = false): string
    {
        return match ($orderType) {
            '生产计划' => '生产计划单',
            '半成品' => '半成品加工单',
            default => $isNull ? '' : '-',
        };
    }
    /**
     * 保存并提交
     * @return bool|string
     */
    public function saveAndCommit(): bool|string
    {
        $resultJson = $this->editEdit();
        $result = json_decode($resultJson,true);
        if ($result['warn'] == 2){
            unset($_SESSION['warn']);
            $resultJson = $this->commitEdit();
        }
        return $resultJson;
    }

    /**
     * 编辑页
     * @return string
     */
    public function edit(): string
    {
        $id = $this->get('id') ?: suiji();
        $info = query(self::table, " id = '" . $id . "' ");

        $button[] = [
            "name" => "保存为草稿",
            "type" => "点击事件",
            "title" => "保存",
            'fun' => "subForm('" . self::page . "EditForm','" . root . "control/adIndex.html?cla=" . self::page . "&fun=editEdit')"
        ];
        $button[] = [
            'style' => 'li-btn-blue-bg',
            "name" => "保存并提交",
            "type" => "点击事件",
            "title" => "保存",
            'fun' => "subForm('" . self::page . "EditForm','" . root . "control/adIndex.html?cla=" . self::page . "&fun=saveAndCommit')"
        ];
        //仓库
        $result = find(array('table' => 'warehouse', 'field' => 'id,name', 'where' => "coid = '" . self::$coid . "' and state = '启用' order by time desc"));
        $tr[] = [
            '',
            '存货类别',
            '物料编码',
            '物料名称',
            '规格型号',
            '单位',
            "<div class='warehouse'><span class='word'>仓库</span>&emsp;" . self::chooseSelect($result['array'], 'warehouseId[]', 'warehouse') . "</div>",
            '数量',
            '批次',
            '源单类别',
            '关联单号',
            '备注'
        ];
        $result = find(array('table' => self::tableMx, 'where' => "orderId = '$info[id]' order by list"));
        foreach ($result['array'] as $k=>$array) {
            $material = query('material', " id = '$array[materialId]'");
            $machiningOrderMx = query('machining_order_mx', "id = '$array[sourceId]'");
            $machiningOrder = query('machining_order', "id = '$machiningOrderMx[orderId]'");
            $unitOption = machiningOrderClass::unitOption($material['id']);
            $orderType = self::orderType($machiningOrder['orderType']);
            $tr[] = [
                componentClass::tablePperation($k+1,"delTableRow(this);calculateTotal()").
                hidden(array('name' => 'mxId[]', 'value' => $array['id'])) .
                hidden(array('name' => 'materialId[]', 'value' => $array['materialId'])) .
                hidden(array('name' => 'sourceId[]', 'value' => $array['sourceId'])),
                $material['subject'],
                $material['code'],
                $material['name'],
                $material['model'],
                select(array('name' => 'unitDetail[]', 'data' => ['unit' => $array['unit']], 'change' => 'unitChange', 'option' => $unitOption, 'title' => '单位', 'value' => $array['unit'])),
                idSelect(array('name' => 'warehouseId[]', 'sqlForm' => "warehouse where coid = '" . self::$coid . "' and state = '启用' order by time desc", 'sqlId' => 'id', 'sqlField' => "name", 'title' => '仓库', 'value' => $array['warehouseId'])),
                text(array('name' => 'num[]', 'other' => self::digitalFiltering('numPrecision')." onblur=\"calculateTotal()\" ", 'value' => self::lostZero($array['num'], 'numPrecision'))),
                text(array('name' => 'batch[]', 'value' => $array['batch'])),
                $orderType,
                $machiningOrder['orderNo'] ?: '-',
                text(array('name' => 'mxText[]', 'value' => $array['text'])),
            ];
        }
        $total      = [
            7  => "<span id='total_num'>" . self::lostZero(array_sum(array_column((array)$result['array'],'num')),'num') . "</span>",
        ];
        $table = $this->listTable(array('tr' => $tr, 'end' => true, 'total' => $total));
        $but = <<<efo
                <span class="smallButton" onclick="chooseOrder('addOrder')">关联生产计划单</span>
                <span class="smallButton" onclick="chooseOrder('addSemiOrder')">关联半成品加工单</span>
                
<!--                         <input id="barcode" style="margin-left: 20px" type="text" class="text" placeholder="输入或扫码"/>-->
<!--                         <label class="checkbox"><input id="cancel_button" type="checkbox" ><span></span>&nbsp;撤销</label>-->
efo;
        //<span class="smallButton" onclick="layer('{$this->get('cla')}','addMx',$('form[name=machiningInOrderEditForm]').serialize())">选择物料</span>
        $line = query('product_line', "id = '$info[lineId]'");
        //表单
        $data['button'] = $this->tableShowButton($button);
        $body = $this->edit4([
            '基本信息' => [
                [
                    must . "生产线：" => repeatSelect(array(
                            'name' => 'workshop',
                            'title' => '生产车间',
                            'change' => "getLine",
                            'sqlForm' => "product_line where coid = '" . self::$coid . "' and state = '启用'",
                            'sqlField' => 'workshop',
                            'value' => $line['workshop']
                        )) .
                        idSelect(array(
                            'name' => 'lineId',
                            'sqlForm' => "product_line where coid = '" . self::$coid . "' and state = '启用' and workshop = '$line[workshop]'",
                            'sqlId' => 'id',
                            'sqlField' => 'name',
                            'title' => '生产线',
                            'value' => $info['lineId']
                        )),
                    must . "经手人：" => selectMultiple([
                            "name" => "manager",
                            "value" => $info['manager'] ?: self::$stid,
                            'table' => "staff",
                            'sqlId' => 'stid',
                            'sqlField' => 'name',
                            'title' => '请选择']
                    ),
                    must . "单据日期：" => text(["name" => "recordDate", 'laydate' => [], "value" => $info['recordDate'] ?: $this->date]),
                ],
                [
                    "备注：" => textarea(["name" => "text", "value" => $info['text']]),
                ],
            ]
        ]);
        $body .= $this->editList([
            'id' => 'materialTable',
            'title' => '完工明细',
            'button' => $but,
            'html' => $table,
        ]);
        $data['html'] = $this->pageEdit([
            "html" => $body,
            'hidden' => hidden(['name' => 'id', 'value' => $id]),
        ]);
        $data['html'] .= $this->js();
        //返回
        return $this->tab($data);
    }

    /**
     * JS
     * @return string
     */
    public function js(): string
    {
        $cla = self::page;
        return <<<eof
<script>

function chooseOrder(classify = 'addOrder'){
    let lineId = $("[name='lineId']").val();
    if (!lineId){
        msg('请先选择生产线','error');
    }else{
        if (classify ==='addOrder'){
            layer('{$this->get('cla')}','addOrder',$('form[name=machiningInOrderEditForm]').serialize())
        }else if(classify ==='addSemiOrder'){
            layer('{$this->get('cla')}','addSemiOrder',$('form[name=machiningInOrderEditForm]').serialize())
        }
    }
    
}

/***扫码操作***/
$("#barcode").on('keydown',function(event) {
    if (event.keyCode==13){
        let code = $(this).val();//条码
        if (!code){
            msg('未找到条码','error')
            return '';
        }
        //判断是否是撤销操作
        if ($("#cancel_button").is(":checked")){
            //撤销
            $.post(root+'control/adIndex.html?cla=pickOrder&fun=getMaterial',{code:code},function(res) {
                  if (res.warn===2){
                      $("#materialTable").find("input[name='materialId[]']").each(function() {
                           if (res.data === $(this).val()){
                               $(this).parent().parent().remove();
                           }
                      });
                  }else{
                      msg(res.warn,'error');
                  }
            },'json')
        }else{
            //添加
             $.post(root+'control/adIndex.html?cla=pickOrder&fun=getMaterial',{code:code},function(res) {
                 if (res.warn===2){
                       $.post(root+'control/adIndex.html?cla={$cla}&fun=addMxEdit',{materialId:res.data,classify:'barcode'},function(res) {
                           if (res.warn ==2){
                               $("#materialTable tbody").append(res.html);
                               resetNumber($("#materialTable"))
                           }else{
                               msg(res.warn,'error');
                           }
                           
                       },'json')
                  }else{
                      msg(res.warn,'error');
                  }
             },'json')
        }
    }
});

//根据单位转换所需数量和库存
function unitChange(e){
    let unit = e.value;
    if (!unit){
        msg('请选择单位')
        return '';
    }
    let oldUnit = $(e).data('unit');
    $(e).data('unit',unit);
    let num = $(e).parent().parent().find("[name='num[]']").val();
    let id = $(e).parent().parent().find("[name='materialId[]']").val();
    $.post(root+'control/adIndex.html?cla={$this->get('cla')}&fun=unitChange',{unit:unit,oldUnit:oldUnit,num:num,id:id},function(res) {
        if (res.warn==2){
            $(e).parent().parent().find("[name='num[]']").val(res.num);
         
        }else{
            msg(res.warn);
        }
    },'json');
}
//获取生产线
function getLine(e){
     let val = e.value;
     $.post(root+'control/adIndex.html?cla=machiningOrder&fun=getLine',{val:val},function(res) {
             $("select[name='lineId']").html(res.html);
        },'json');
}

function addRow(classify = ''){
    if (classify ==='machiningOrder'){
        $.post(root+'control/adIndex.html?cla={$this->get('cla')}&fun=addOrderEdit',$("form[name='machiningOrderForm']").serialize(),function(res) {
            if (res.warn ==2){
                $('#machiningInOrderAddOrder').hide();
                $("#materialTable tbody").append(res.html);
                resetNumber($("#materialTable"))
                calculateTotal()
            }else{
                msg(res.warn)
            }
        },'json');
    } else if(classify ==='semiOrder'){
         $.post(root+'control/adIndex.html?cla={$this->get('cla')}&fun=addSemiOrderEdit',$("form[name='semiOrderForm']").serialize(),function(res) {
            if (res.warn ==2){
               $('#machiningInOrderAddSemiOrder').hide()
                $("#materialTable tbody").append(res.html);
                resetNumber($("#materialTable"))
                calculateTotal()
            }else{
                msg(res.warn)
            }
        },'json');
    }else{
         $.post(root+'control/adIndex.html?cla={$this->get('cla')}&fun=addMxEdit',$("form[name='mxForm']").serialize(),function(res) {
            if (res.warn ==2){
                $('#machiningInOrderAddMx').hide();
                $("#materialTable tbody").append(res.html);
                resetNumber($("#materialTable"))
                calculateTotal()
            }else{
                msg(res.warn)
            }
        },'json');
    }
}
//计算计划数量
function calculateTotal(table=''){
    table = table ? table : $('.editList')
    let num = 0
    table.find("[name='num[]']").each(function(index){
        if($(this).val()){
          num+=Number($(this).val());
        }
    })
    $("#total_num").text(num.toFixed(publicSettings.numPrecision.num));
}
</script>
eof;

    }


    /**
     * 根据单位显示所需数量
     */
    public function unitChange()
    {
        $materialId = $this->post('id');
        $num = $this->post('num');
        $unit = $this->post('unit');
        $oldUnit = $this->post('oldUnit');
        if (empty($materialId)) {
            $json['warn'] = '未找到物料';
        } elseif (empty($unit)) {
            $json['warn'] = '未找到单位';
        } else {
            $json['warn'] = 2;
            $json['num'] = $num;
            if ($oldUnit) {
                $num = machiningOrderClass::material_num_change($materialId, $oldUnit, $unit, $num);
                $json['num'] = $num;
            }
            $inventoryNum = self::lostZero(machiningOrderClass::inventory($materialId, $unit), 'numPrecision');
            $json['inventoryNum'] = $inventoryNum;
        }
        return json_encode($json, 320);
    }

    public function editEdit()
    {
        $id = $this->post('id') ?: self::getId();
        $mxIdArr = $this->post('mxId') ?: [];
        $materialIdArr = $this->post('materialId');
        $sourceIdArr = $this->post('sourceId');
        $numArr = $this->post('num');
        $unitArr = $this->post('unitDetail');
        $batchArr = $this->post('batch');
        $mxTextArr = $this->post('mxText');
        $warehouseIdArr = $this->post('warehouseId');

        $field = [
            'text' => $this->post('text'),
            'lineId' => $this->post('lineId'),
            'manager' => $this->post('manager'),
            'recordDate' => $this->post('recordDate'),
        ];
        $where = " id = '$id' ";
        $info = query(self::table, $where);
        //判断
        if (!$this->power(self::page, "edit")) {
            $json['warn'] = "你没有编辑" . self::title . "的权限";
        } elseif (!empty($info['id']) && $info['state'] == '已确认') {
            $json['warn'] = '此生产入库单已确认，不能修改';
        } else {
            $json['warn'] = '';
            if (empty($json['warn'])) {
                $this->startTrans();
                $isPass = true;//事务通过标志
                if (!$info['id']) {
                    $userNo = codeTemplateClass::generateCode(self::page, [
                        'prefix' => 'SCRK' . date('Ymd', strtotime($field['recordDate'])),
                        'table' => self::table,
                        'field' => 'orderNo',
                        'where' => " and coid = '" . self::$coid . "'",
                    ], $field);
                    $field = array_merge($field, [
                        'id' => $id,
                        'orderNo' => $userNo,
                        'state' => '草稿',
                        'coid' => self::$coid,
                        'stid' => $this->control['stid'],
                    ]);
                    $json['warn'] = static::insert(["table" => self::table, "field" => $field]);
                } else {
                    $json['warn'] = static::update([
                        "table" => self::table,
                        "field" => $field,
                        "where" => $where
                    ]);
                }

                //添加或更新明细

                foreach ($mxIdArr as $k => $nid) {
                    $mx = query(self::tableMx, "id = '$nid'");
                    $numArr[$k] = self::formattingFigure($numArr[$k], 'numPrecision');
                    if (!empty($mx['id'])) {
                        //更新
                        $warn = static::update([
                            "table" => self::tableMx,
                            "field" => [
                                'sourceId' => $sourceIdArr[$k],
                                'materialId' => $materialIdArr[$k],
                                'num' => $numArr[$k],
                                'unit' => $unitArr[$k],
                                'warehouseId' => $warehouseIdArr[$k],
                                'text' => $mxTextArr[$k],
                                'batch' => $batchArr[$k],
                            ],
                            "where" => " id = '$nid'"
                        ]);
                    } else {
                        //新增
                        $warn = static::insert([
                            "table" => self::tableMx,
                            "field" => [
                                'id' => $nid,
                                'orderId' => $id,
                                'coid' => self::$coid,
                                'sourceId' => $sourceIdArr[$k],
                                'materialId' => $materialIdArr[$k],
                                'num' => $numArr[$k],
                                'unit' => $unitArr[$k],
                                'warehouseId' => $warehouseIdArr[$k],
                                'text' => $mxTextArr[$k],
                                'batch' => $batchArr[$k],
                            ],

                        ]);
                    }
                    if (!in_array($warn, ['新增成功', '更新成功'])) {
                        $isPass = false;
                        $json['warn'] = $warn;
                        break;
                    }
                }

                if (in_array($json['warn'], ["新增成功", "更新成功"]) && $isPass) {
                    $this->commitTrans();
                    delete(array('table' => self::tableMx, 'where' => " id not in ('" . implode("','", $mxIdArr) . "') and orderId = '$id'"));
                    if ($json['warn'] == '新增成功') {
                        self::insertOperateLog($id,self::title,"新建");
                    }
                    //添加日志
                    $type = mb_substr($json['warn'], 0, 2, 'utf-8');
                    $text = $this->control['name'] . $type . "了" . self::title . " id：【" . $id . '】';
                    $this->logText(["type" => self::page, "text" => $text]);
                    //返回
                    $_SESSION['warn'] = $json['warn'];
                    $json['warn'] = 2;
                    $json['href'] = root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=detail&id=" . $id;
                } else {
                    $this->rollback();
                }
            }
        }

        resp:
        return json_encode($json, 320);
    }

    /**
     * 关联半成品加工单
     */
    public function addSemiOrder()
    {
        $html =
            text(array("name" => "orderNo", "title" => "半成品加工单号")) .
            text(array("name" => "recordDate", 'class' => 'width200', 'laydate' => ['type' => 'date', 'range' => '~'], "title" => "单据日期-单据日期")) .
            text(array("name" => "code", "title" => "产品编码")) .
            text(array("name" => "name", "title" => "产品名称")) .
            hidden(array('name' => 'id', 'value' => $this->post('id'))) .
            hidden(array('name' => 'lineId', 'value' => $this->post('lineId'))) .
            hidden(array('name' => 'sourceId', 'value' => $this->post('sourceId') ? implode(',', $this->post('sourceId')) : ''));
        $button = "<input onclick=\"addRow('semiOrder')\" type='button' class='searchSub m-l-5' value='提交'>";
        $html = $this->search($html);
        return $this->layer(array("title" => "添加", "height" => 600, "width" => 1000, "html" => $html, "button" => $button));
    }

    public function addSemiOrderSearch()
    {
        return $this->addOrderSearch('半成品');
    }

    public function addSemiOrderEdit()
    {
        $id = $this->post('id');//采购订单ID
        $mxIdArr = $this->post('machiningOrderMxId');
        if (!$this->power(self::page, 'edit')) {
            $json['warn'] = '你还没有编辑权限';
        } elseif (empty($mxIdArr) || !is_array($mxIdArr)) {
            $json['warn'] = '请选择半成品加工单';
        } else {
            $json['html'] = '';
            $tr = [];
            foreach ($mxIdArr as $machiningOrderMxId) {
                $machining_order_mx = query('machining_order_mx', "id = '$machiningOrderMxId'");
                $machining_order = query('machining_order', "id = '$machining_order_mx[orderId]'");
                $material = query('material', "id = '$machining_order_mx[materialId]'");
                $unitOption = machiningOrderClass::unitOption($material['id']);
                //单位选项
                $select = select(array(
                    'name' => 'unitDetail[]',
                    'data' => ['unit' => $machining_order_mx['unit']],
                    'change' => 'unitChange',
                    'option' => $unitOption,
                    'title' => '单位',
                    'value' => $machining_order_mx['unit']
                ));
                //仓库选项
                $warehouse = idSelect(array(
                    'name' => 'warehouseId[]',
                    'sqlForm' => "warehouse where coid = '" . self::$coid . "' and state = '启用' order by time desc",
                    'sqlId' => 'id',
                    'sqlField' => "name",
                    'title' => '仓库'
                ));
                //已进入生产入库单的生产计划单明细数量
                $all = find(array(
                    'table' => 'machining_in_order_detail',
                    'where' => "orderId !='$id' and sourceId = '$machining_order_mx[id]' and coid = '" . self::$coid . "' and materialId = '$material[id]'"
                ));
                $orderNum = 0;
                foreach ($all['array'] as $val) {
                    $orderNum += machiningOrderClass::material_num_change($material['id'], $val['unit'], $machining_order_mx['unit'], $val['num']);
                }
                $num = ($machining_order_mx['num'] - $orderNum) > 0 ? self::formattingFigure($machining_order_mx['num'] - $orderNum, 'numPrecision') : 0;
                $suiji = self::getId();
                $tr[] = [
                    componentClass::tablePperation('',"delTableRow(this);calculateTotal()").
                    hidden(array('name' => 'mxId[]', 'value' => $suiji)) .
                    hidden(array('name' => 'materialId[]', 'value' => $material['id'])) .
                    hidden(array('name' => 'sourceId[]', 'value' => $machining_order_mx['id'])),
                    $material['subject'],
                    $material['code'],
                    $material['name'],
                    $material['model'],
                    $select,
                    $warehouse,
                    text(array('name' => 'num[]', 'other' => self::digitalFiltering('numPrecision')." onblur=\"calculateTotal()\" ", 'value' => self::lostZero($num, 'numPrecision'))),
                    text(array('name' => 'batch[]', 'value' => $machining_order_mx['batch'])),
                    '半成品加工单',
                    $machining_order['orderNo'],
                    text(array('name' => 'mxText[]','value'=>$machining_order_mx['text']?:$machining_order['text'])),
                ];
            }
            $json['warn'] = 2;
            $json['html'] = $this->tableMany(['tr' => $tr, 'thead' => false]);
        }
        return json_encode($json, 320);
    }

    /**
     * 关联生产计划单
     * @return bool|string
     */
    public function addOrder(): bool|string
    {
        $html =
            text(array("name" => "orderNo", "title" => "生产计划单号")) .
            text(array("name" => "recordDate", 'class' => 'width200', 'laydate' => ['type' => 'date', 'range' => '~'], "title" => "单据日期-单据日期")) .
            text(array("name" => "code", "title" => "产品编码")) .
            text(array("name" => "name", "title" => "产品名称")) .
            hidden(array('name' => 'id', 'value' => $this->post('id'))) .
            hidden(array('name' => 'lineId', 'value' => $this->post('lineId'))) .
            hidden(array('name' => 'sourceId', 'value' => $this->post('sourceId') ? implode(',', $this->post('sourceId')) : ''));
        $button = "<input onclick=\"addRow('machiningOrder')\" type='button' class='searchSub m-l-5' value='提交'>";
        $html = $this->search($html);
        return $this->layer(array("title" => "添加", "height" => 600, "width" => 1000, "html" => $html, "button" => $button));
    }

    /**
     * 关联生产计划单
     * @param string $orderType
     * @return bool|string
     */
    public function addOrderSearch($orderType = '生产计划'): bool|string
    {
        //$sourceId = $this->post('sourceId') ? explode(',', $this->post('sourceId')) : [];
        //$where = " id not in  (select distinct orderId from machining_order_mx where id in ('" . implode("','", $sourceId) . "'))";
        $where = '';
        $and = " and a.isClose = 0";
        $like = [
            'a.orderNo' => $this->post('orderNo'),
            'c.code' => $this->post('code'),
            'c.name' => $this->post('name'),
        ];
        $equal = [
            'a.coid' => self::$coid,
            'a.orderType' => $orderType,
            'a.state' => '已确认',
            'a.lineId' => $this->post('lineId')
        ];
        if ($this->post('recordDate')) {
            //单据日期
            $and .= self::timeComparison($this->post('recordDate'), field: 'a.recordDate');
        }
        $where .= search(["like" => $like, "=" => $equal]) . $and;
        $page = $this->page([
            "table" => "machining_order as a join machining_order_mx as b on a.id = b.orderId join material as c on b.materialId = c.id",
            "where" => $where,
            'pageNum' => 50,
            "order" => "a.recordDate desc,a.`orderNo` desc,b.list",
            'field' => "a.orderNo,a.lineId,a.recordDate,c.name,c.code,c.model,a.text as mainText,b.*",
        ]);
        $form = 'machiningOrderForm';
        $title = '生产计划单号';
        if ($orderType == '半成品') {
            $form = 'semiOrderForm';
            $title = '半成品加工单号';
        }
        //获取表头
        $checkAll = $this->checkAll($form, "machiningOrderMxId");
        $tr[] = [$checkAll, $title, '生产线', '单据日期', '产品编码', '产品名称', '规格型号', '单位', '未入库数量' . componentClass::tipComponent('在已确认的生产入库单中的数量'),'备注'];

        //获取记录
        foreach ($page['array'] as $array) {
            $dominate = array(
                "box" => array("name" => "machiningOrderMxId", "value" => $array['id']),
            );
            $line = query('product_line', "id = '$array[lineId]'");
            //在已确认的生产入库单中的数量
            $inStockNum = $this->inMachiningInOrder($array['id'],$this->post('id'), $array['unit']);
            $tr[] = array(
                $this->dominate($dominate),
                $array['orderNo'],
                $line['workshop'] . '-' . $line['name'],
                $array['recordDate'],
                $array['code'],
                $array['name'],
                $array['model'],
                $array['unit'],
                self::lostZero($array['num'] - $inStockNum, 'numPrecision'),
                $array['text']?:$array['mainText']
            );
        }
        $json['html'] = $page['hint'] .
            "<form name='{$form}'>" .
                hidden(array('name' => 'id', 'value' => $this->post('id'))) .
                $this->tableMany(array("tr" => $tr, "showSort" => true, "page" => $page['para'])) .
            "</form>" .
            $page['button'];
        return json_encode($json, 320);
    }

    /**
     * 已在已确认的生产入库单中的数量
     * @param $machiningOrderMxId
     * @param $id
     * @param $unit
     * @return float|int
     */
    public function inMachiningInOrder($machiningOrderMxId,$id, $unit): float|int
    {
        //已进入生产入库单的生产计划单明细数量
        $all = find(array('table' => 'machining_in_order_detail', 'where' => "orderId !='$id' and sourceId = '$machiningOrderMxId' and coid = '" . self::$coid . "'"));
        $num = 0;
        foreach ($all['array'] as $val) {
            $num += machiningOrderClass::material_num_change($val['materialId'], $val['unit'], $unit, $val['num']);
        }
        return $num;
    }
    /**
     * 关联生产计划单
     */
    public function addOrderEdit()
    {
        $id = $this->post('id');//
        $mxIdArr = $this->post('machiningOrderMxId');
        if (!$this->power(self::page, 'edit')) {
            $json['warn'] = '你还没有编辑权限';
        } elseif (empty($mxIdArr) || !is_array($mxIdArr)) {
            $json['warn'] = '请选择生产计划产品';
        } else {
            $json['html'] = '';
            $tr = [];
            foreach ($mxIdArr as $machiningOrderMxId) {
                $machining_order_mx = query('machining_order_mx', "id = '$machiningOrderMxId'");
                $machining_order = query('machining_order', "id = '$machining_order_mx[orderId]'");
                $material = query('material', "id = '$machining_order_mx[materialId]'");
                $unitOption = machiningOrderClass::unitOption($material['id']);
                //单位选项
                $select = select(array(
                    'name' => 'unitDetail[]',
                    'data' => ['unit' => $machining_order_mx['unit']],
                    'change' => 'unitChange',
                    'option' => $unitOption,
                    'title' => '单位',
                    'value' => $machining_order_mx['unit']
                ));
                //仓库选项
                $warehouse = idSelect(array(
                    'name' => 'warehouseId[]',
                    'sqlForm' => "warehouse where coid = '" . self::$coid . "' and state = '启用' order by time desc",
                    'sqlId' => 'id',
                    'sqlField' => "name",
                    'title' => '仓库'
                ));
                //已进入生产入库单的生产计划单明细数量
                $orderNum = $this->inMachiningInOrder($machining_order_mx['id'],$id,$machining_order_mx['unit']);
                $num = ($machining_order_mx['num'] - $orderNum) > 0 ? self::formattingFigure($machining_order_mx['num'] - $orderNum, 'numPrecision') : 0;
                $suiji = self::getId();
                $tr[] = [
                    componentClass::tablePperation('',"delTableRow(this);calculateTotal()").
                    hidden(array('name' => 'mxId[]', 'value' => $suiji)) .
                    hidden(array('name' => 'materialId[]', 'value' => $material['id'])) .
                    hidden(array('name' => 'sourceId[]', 'value' => $machining_order_mx['id'])),
                    $material['subject'],
                    $material['code'],
                    $material['name'],
                    $material['model'],
                    $select,
                    $warehouse,
                    text(array('name' => 'num[]', 'other' => self::digitalFiltering('numPrecision')." onblur=\"calculateTotal()\" ", 'value' => self::lostZero($num, 'numPrecision'))),
                    text(array('name' => 'batch[]', 'value' => $machining_order_mx['batch'])),
                    '生产计划单',
                    $machining_order['orderNo'],
                    text(array('name' => 'mxText[]','value'=>$machining_order_mx['text']?:$machining_order['text'])),
                ];
            }
            $json['warn'] = 2;
            $json['html'] = $this->tableMany(['tr' => $tr, 'thead' => false]);
        }
        return json_encode($json, 320);
    }


    /**
     *
     * @return bool|string
     */
    public function addMx()
    {
        $materialClassObj = new materialClass();
        $layerId          = $this->get('cla') . ucwords($this->get('fun'));
        $formName         = 'mxForm';
        $notAllowRepeat   = '';
        $data             = [
            'sub'            => " onclick=\"addRow();$('#" . $layerId . "').remove()\" ",
            'continueAdding' => $notAllowRepeat ? " onclick=\"addRow();removeSelectedContent('" . $formName . "')\" " : " onclick=\"addRow();\" ",
            'hidden'         => hidden(["name" => "notAllowRepeat", "value" => $notAllowRepeat]) .
                hidden(array('name' => 'materialId', 'value' => $this->post('materialId') ? implode(',', $this->post('materialId')) : '')),
        ];
        return $materialClassObj->addMx($data);
    }

    /**
     * 编辑
     *
     * @return bool|string
     */
    public function addMxEdit()
    {
        $mxIdArr = $this->post('mxId');
        $materialId = $this->post('materialId');
        $classify = $this->post('classify');//扫码添加类型
        if (!$this->power(self::page, 'edit')) {
            $json['warn'] = '你还没有编辑权限';
        } elseif ($classify !== 'barcode' && (empty($mxIdArr) || !is_array($mxIdArr))) {
            $json['warn'] = '请选择物料';
        } elseif ($classify === 'barcode' && empty($materialId)) {
            $json['warn'] = '未找到物料';
        } else {
            if ($classify === 'barcode') {
                $mxIdArr[] = $materialId;
            }
            $tr = [];
            foreach ($mxIdArr as $mxId) {
                $material = query('material', "id = '$mxId'");
                $unitOption = machiningOrderClass::unitOption($material['id']);
                $select = select(array(
                    'name' => 'unitDetail[]',
                    'data' => ['unit' => $material['unit']],
                    'change' => 'unitChange',
                    'option' => $unitOption,
                    'title' => '单位',
                    'value' => $material['unit']
                ));
                //仓库选项
                $warehouse = idSelect(array(
                    'name' => 'warehouseId[]',
                    'sqlForm' => "warehouse where coid = '" . self::$coid . "' and state = '启用' order by time desc",
                    'sqlId' => 'id',
                    'sqlField' => "name",
                    'title' => '仓库'
                ));
                $suiji = self::getId();
                $tr[] = [
                    componentClass::tablePperation('',"delTableRow(this);calculateTotal()").
                    hidden(array('name' => 'mxId[]', 'value' => $suiji)) .
                    hidden(array('name' => 'materialId[]', 'value' => $mxId)) .
                    hidden(array('name' => 'sourceId[]')),
                    $material['subject'],
                    $material['code'],
                    $material['name'],
                    $material['model'],
                    $select,
                    $warehouse,
                    text(array('name' => 'num[]', 'other' => self::digitalFiltering('numPrecision')." onblur=\"calculateTotal()\" ")),
                    text(array('name' => 'batch[]')),
                    '-',
                    '-',
                    text(array('name' => 'mxText[]')),
                ];
            }
            $json['warn'] = 2;
            $json['html'] = $this->tableMany(['tr' => $tr, 'thead' => false]);
        }
        return json_encode($json, 320);
    }


    /*详情页*/
    public function detail(): string
    {
        $info = query(self::table, " id = '{$this->get('id')}'");
        if (empty($info['id'])) {
            $html = '未找到此' . self::title;
        } else {
            //菜单
            $data = array(
                "id" => $info['id'],
            );

            $button = [];
            if ($this->power(self::page, "confirm") && $info['state'] == '待确认') {
                $button[] = [
                    "name" => "复核",
                    "type" => "点击事件",
                    "cla" => $this->get('cla'),
                    "fun" => "confirmInOrder('{$info['id']}')",
                    'style' => 'li-btn-blue-bg',
                ];
            }
            if ($this->power(self::page, "confirm") && $info['state'] != '草稿') {
                $button[] = [
                    "name" => "撤回",
                    "type" => "弹出层",
                    "cla" => $this->get('cla'),
                    "fun" => "operate",
                    "post" => ["act" => 'cancel', "id" => $info['id']],
                ];
            }

            if ($info['state'] == '草稿') {
                if ($this->power(self::page, "edit")) {
                    //按钮
                    $button[] = [
                        "name" => "提交",
                        "type" => "弹出层",
                        "cla" => $this->get('cla'),
                        "fun" => "operate",
                        "post" => ["act" => 'commit', "id" => $info['id']],
                        'style' => 'li-btn-blue-bg',
                    ];
                    //按钮
                    $button[] = [
                        "name" => "编辑",
                        "type" => "顶部页卡",
                        "title" => "编辑用户",
                        "url" => $this->root . "control/adIndex.html?cla={$this->get('cla')}&fun=edit&id=" . $info['id'],

                    ];
                }
                if ($this->power(self::page, "del")) {
                    //按钮
                    $button[] = [
                        "name" => "删除",
                        "type" => "弹出层",
                        "cla" => $this->get('cla'),
                        "fun" => "operate",
                        "post" => ["act" => 'del', "id" => $info['id']],
                    ];
                }

            }


            $button[] = [
                "name" => "单据追踪",
                "type" => "顶部页卡",
                "title" => "单据追踪",
                "url" => $this->root . "control/adIndex.html?cla=orderTrack&fun=home&orderType=生产入库单&id=" . $info['id'],
            ];
            //操作记录
            $button[] = self::operateLogBut($info['id'],1);

            $total = find(array('table' => self::tableMx, 'field' => "sum(num) as num", 'single' => "orderId = '$info[id]'"));
            $total['num'] = $total['num'] ? self::lostZero($total['num'], 'numPrecision') : 0;

            $tr[] = ['存货类型', '物料编码', '物料名称', '规格型号', '单位', "仓库", '数量', '批次', '源单类型', '关联单号', '备注'];
            $result = find(array('table' => self::tableMx, 'where' => "orderId = '$info[id]' order by list"));
            foreach ($result['array'] as $array) {
                $material = query('material', " id = '$array[materialId]'");
                $machiningOrderMx = query('machining_order_mx', "id = '$array[sourceId]'");
                $machiningOrder = query('machining_order', "id = '$machiningOrderMx[orderId]'");
                $warehouse = query('warehouse', "id = '$array[warehouseId]'");
                $tr[] = [
                    $material['subject'],
                    $material['code'],
                    $material['name'],
                    $material['model'],
                    $array['unit'],
                    $warehouse['name'],
                    self::lostZero($array['num'], 'numPrecision'),
                    $array['batch'],
                    $machiningOrder['orderType'] == '生产计划' ? '生产计划单' : '半成品加工单',
                    $machiningOrder['orderNo'],
                    $array['text'],
                ];
            }
            $total_tr = [
                    6=>$total['num']
            ];

            $line = query('product_line', "id = '$info[lineId]'");
            //生成表单
            $data['button'] = $this->tableShowButton($button);
            $data['html'] = $this->tableShow(array(
                "基本信息" => array(
                    array(
                        "生产线" => $line['workshop'] . '-' . $line['name'],
                        "经手人" => self::findStaff($info['manager']),
                        "单据日期" => $info['recordDate'],
                        "单据编号" => $info['orderNo'],
                    ),
                    array(
                        "制单人" => self::findStaff($info['stid']),
                        "状态" => $info['state']
                    ),
                    array(
                        "备注" => pre($info['text']),
                    ),
                ),
            ));
            $data['html'] .= $this->detailList([
                'title' => '完工明细',
                'html' => $this->listTable(array('tr' => $tr, 'showEmpty' => true, 'total' => $total_tr, 'showSort' => true)),
            ]);
            $data['html'] .= <<<eof
<script>
function confirmInOrder(id){
    $.post(root+'control/adIndex.html?cla=machiningInOrder&fun=judgeInspectionNumCtrl',{id:id},function (res){
        if (res.warn ===2){
            layer('machiningInOrder','operate',{act:'confirm',id:id})
        }else{
            if (res.data.method ==='提交'){
                  layer('machiningInOrder','operate',{act:'confirm',id:id})
            }else if(res.data.method ==='密码'){
                 layer('machiningInOrder','operate',{act:'confirm',id:id,pwd:'1',title:res.warn+'，是否继续确认此订单?'})
            }else{
                 msg(res.warn,'error');
            }
        }
    },'json')
}
</script>
eof;

            //生成页面
            $html = $this->tab($data);
        }
        //返回
        return $html;
    }

    public function judgeInspectionNumCtrl(): bool|string
    {
        $id = $this->post('id');
        $info = query(self::table, " id = '$id'");
        if (!$this->power(self::page, 'confirm')) {
            $json['warn'] = '你还没有确认权限';
        } elseif (empty($info['id'])) {
            $json['warn'] = '未找到此生产入库单';
        } elseif ($info['state'] != '待确认') {
            $json['warn'] = '此生产入库单不是待确认状态，不能确认';
        } else {
            $res = $this->inspectionNumCtrl($id);
            if ($res['tip'] !== true) {
                $json['warn'] = $res['tip'];
            } else {
                $json['warn'] = 2;
            }
            //入库
            if ($res['settingType'] == '质量') {
                $setting = optionSettingClass::getSetting('质量');
                if (isset($setting['productNumControll']['option']) && $setting['productNumControll']['option'] && isset($setting['productNumControll']['method'])) {
                    $json['data']['method'] = $setting['productNumControll']['method'] ?? '提交';
                }
            } elseif ($res['settingType'] == '生产') {
                $setting = optionSettingClass::getSetting('生产');
                if (isset($setting['productWithOutCheck']['option']) && $setting['productWithOutCheck']['option'] && isset($setting['productWithOutCheck']['method'])) {
                    $json['data']['method'] = $setting['productWithOutCheck']['method'] ?? '提交';
                }
            }
            $json['data']['method'] = $json['data']['method'] ?? '提交';
        }
        return json_encode($json, 320);
    }

    /**
     * 成品报检数量控制
     */
    public function inspectionNumCtrl($id): array
    {
        $tip = true;
        $settingType = '';
        $info = query(self::table, "id = '$id'");
        $quality = [];//质检分组
        $unQuality = [];//未启用质检的产品
        $result = find(array('table' => self::tableMx, 'where' => "orderId = '$info[id]' order by list asc"));
        foreach ($result['array'] as $array) {
            $material = query('material', "id = '$array[materialId]'");
            if ($material['IPQC']) {
                //质检
                $quality[$array['materialId']][$array['id']] = ['num' => $array['num']];
            } else {
                $unQuality[$array['materialId']][$array['id']] = ['num' => $array['num']];
            }
        }
        //入库
        $setting = optionSettingClass::getSetting('质量');

        //质检
        if (isset($setting['productNumControll']['option']) && $setting['productNumControll']['option']) {
            foreach ($quality as $materialId => $array) {
                foreach ($array as $mxId => $item) {
                    $mx = query(self::tableMx, "id = '$mxId'");
                    if (isset($setting['productNumControll']['way'])) {
                        $qualityNum = 0;
                        $machiningOrderMx = query('machining_order_mx', "id = '$mx[sourceId]'");
                        //从工艺路线中找出末工序
                        $routingDetail = find(array(
                            'table' => "routing as a join routing_detail as b on a.id = b.orderId",
                            "single" => "a.id = '" . $machiningOrderMx['routingId'] . "' and b.mark = '尾工序' order by b.list desc",
                            'field' => "b.processId"
                        ));
                        if (!empty($routingDetail['processId'])) {
                            $allSendOrder = find(array(
                                'table' => 'machining_send_order',
                                "where" => "machiningOrderMxId = '$machiningOrderMx[id]' order by time"
                            ));
                            $warn = '未在质量选项设置中找到控制类型';
                            if ($setting['productNumControll']['way'] == 'finalProcess') {
                                //末工序合格数量
                                foreach ($allSendOrder['array'] as $machiningSendOrder) {
                                    //末工序报工
                                    $allLaseProcessReport = find(array(
                                        'table' => 'process_report',
                                        "where" => "sendId = '$machiningSendOrder[id]' and processId = '$routingDetail[processId]' order by time"
                                    ));
                                    foreach ($allLaseProcessReport['array'] as $processReport) {
                                        $qualityNum += $processReport['yield'] - $processReport['badNum'];
                                    }
                                }
                                $warn = '报检数量超出了末工序合格数量';
                            } elseif ($setting['productNumControll']['way'] == 'finalProcessWithNum') {
                                //末工序合格+不合格数量
                                foreach ($allSendOrder['array'] as $machiningSendOrder) {
                                    //末工序报工
                                    $allLaseProcessReport = find(array(
                                        'table' => 'process_report',
                                        "where" => "sendId = '$machiningSendOrder[id]' and processId = '$routingDetail[processId]' order by time"
                                    ));
                                    foreach ($allLaseProcessReport['array'] as $processReport) {
                                        $qualityNum += $processReport['yield'];
                                    }
                                }
                                $warn = '报检数量超出了末工序合格+不合格数量';
                            } elseif ($setting['productNumControll']['way'] == 'finalProcessWithAllNum') {
                                //末工序合格+全部工序不合格数量
                                foreach ($allSendOrder['array'] as $machiningSendOrder) {
                                    //末工序合格
                                    $allLaseProcessReport = find(array(
                                        'table' => 'process_report',
                                        "where" => "sendId = '$machiningSendOrder[id]' and processId = '$routingDetail[processId]' order by time"

                                    ));
                                    foreach ($allLaseProcessReport['array'] as $processReport) {
                                        $qualityNum += $processReport['yield'] - $processReport['badNum'];
                                    }
                                    //全部工序不合格
                                    $allLaseProcessReport = find(array('table' => 'process_report', "where" => "sendId = '$machiningSendOrder[id]' order by time"));
                                    foreach ($allLaseProcessReport['array'] as $processReport) {
                                        $qualityNum += $processReport['badNum'];
                                    }
                                }
                                $warn = '报检数量超出了末工序合格+全部工序不合格数量';
                            }
                            if ($item['num'] > self::formattingFigure($qualityNum, 'numPrecision')) {
                                $tip = "【" . materialClass::getName($materialId) . "】" . $warn;
                                $settingType = '质量';
                            }
                        }
                    }
                }
            }
        }

        $setting = optionSettingClass::getSetting('生产');
        if (isset($setting['productWithOutCheck']['option']) && $setting['productWithOutCheck']['option']) {
            foreach ($unQuality as $materialId => $array) {
                foreach ($array as $mxId => $item) {
                    $mx = query(self::tableMx, "id = '$mxId'");
                    if (isset($setting['productWithOutCheck']['way'])) {
                        $qualityNum = 0;
                        $machiningOrderMx = query('machining_order_mx', "id = '$mx[sourceId]'");
                        //从工艺路线中找出末工序
                        $routingDetail = find(array(
                            'table' => "routing as a join routing_detail as b on a.id = b.orderId",
                            "single" => "a.id = '" . $machiningOrderMx['routingId'] . "' and b.mark = '尾工序' order by b.list desc",
                            'field' => "b.processId"
                        ));
                        $allSendOrder = find(array('table' => 'machining_send_order', "where" => "machiningOrderMxId = '$machiningOrderMx[id]' order by time"));
                        if (!empty($routingDetail['processId'])) {
                            $warn = '未在生产选项设置中找到控制类型';
                            if ($setting['productWithOutCheck']['way'] == 'endNum') {
                                //末工序合格数量
                                foreach ($allSendOrder['array'] as $machiningSendOrder) {
                                    //末工序报工
                                    $allLaseProcessReport = find(array(
                                        'table' => 'process_report',
                                        "where" => "sendId = '$machiningSendOrder[id]' and processId = '$routingDetail[processId]' order by time"
                                    ));
                                    foreach ($allLaseProcessReport['array'] as $processReport) {
                                        $qualityNum += $processReport['yield'] - $processReport['badNum'];
                                    }
                                }
                                $warn = '入库数量超出了末工序合格数量';
                            } elseif ($setting['productWithOutCheck']['way'] == 'endAndFailed') {
                                //末工序合格+不合格数量
                                foreach ($allSendOrder['array'] as $machiningSendOrder) {
                                    //末工序报工
                                    $allLaseProcessReport = find(array(
                                        'table' => 'process_report',
                                        "where" => "sendId = '$machiningSendOrder[id]' and processId = '$routingDetail[processId]' order by time"
                                    ));
                                    foreach ($allLaseProcessReport['array'] as $processReport) {
                                        $qualityNum += $processReport['yield'];
                                    }
                                }
                                $warn = '入库数量超出了末工序合格+不合格数量';
                            } elseif ($setting['productWithOutCheck']['way'] == 'endAndAllFailed') {
                                //末工序合格+全部工序不合格数量
                                foreach ($allSendOrder['array'] as $machiningSendOrder) {
                                    //末工序合格
                                    $allLaseProcessReport = find(array(
                                        'table' => 'process_report',
                                        "where" => "sendId = '$machiningSendOrder[id]' and processId = '$routingDetail[processId]' order by time"
                                    ));
                                    foreach ($allLaseProcessReport['array'] as $processReport) {
                                        $qualityNum += $processReport['yield'] - $processReport['badNum'];
                                    }
                                    //全部工序不合格
                                    $allLaseProcessReport = find(array('table' => 'process_report', "where" => "sendId = '$machiningSendOrder[id]' order by time"));
                                    foreach ($allLaseProcessReport['array'] as $processReport) {
                                        $qualityNum += $processReport['badNum'];
                                    }
                                }
                                $warn = '入库数量超出了末工序合格+全部工序不合格数量';
                            }

                            if ($item['num'] > self::formattingFigure($qualityNum, 'numPrecision')) {
                                $tip = "【" . materialClass::getName($materialId) . "】" . $warn;
                                $settingType = '生产';
                            }
                        }

                    }
                }
            }
        }

        return ['tip' => $tip, 'settingType' => $settingType];
    }

    /**
     * 生产计划控制
     * @param $id
     * @return bool|string
     */
    public function inCtrl($id): bool|string
    {
        $info = query(self::table, " id = '$id'");
        $setting = optionSettingClass::getSetting('生产');
        if (isset($setting['machiningOrderPickStrict']['option']) && $setting['machiningOrderPickStrict']['option']) {
            $all = find(array('table' => self::tableMx, "where" => "orderId = '$info[id]' order by list"));
            if ($setting['machiningOrderPickStrict']['method'] == 'afterPick') {
                //生产有领料后方可入库/质检
                foreach ($all['array'] as $array) {
                    $machining_order_mx = query('machining_order_mx', "id = '$array[sourceId]'");
                    if (static::total(array('table' => 'pick_order_detail as a join pick_order as b on a.orderId = b.id', 'where' => "b.state = '已确认' and b.type=0 and a.sourceId in (select id from machining_order_detail where orderId = '$machining_order_mx[orderId]') ")) == 0) {
                        return "【" . materialClass::getName($array['materialId']) . "】没有领料记录，暂不能确认";
                    }
                }
            } elseif ($setting['machiningOrderPickStrict']['method'] == 'pick') {
                //按照生产领料齐套数量严格入库/质检
                foreach ($all['array'] as $array) {
                    $machining_order_mx = query('machining_order_mx', "id = '$array[sourceId]'");
                    //所需物料数量
                    $outsource_process_Detail_all = find(array(
                        'table' => 'machining_order_detail',
                        'where' => "targetSkuId = '$machining_order_mx[id]' and coid = '" . self::$coid . "' and orderId = '$machining_order_mx[orderId]'"
                    ));
                    foreach ($outsource_process_Detail_all['array'] as $detail) {
                        $material = query('material', "id = '$detail[materialId]'");
                        $needNum = machiningOrderClass::material_num_change($detail['materialId'], $detail['unit'], $material['unit'], $detail['num']);
                        //已发料书数量
                        $sendAll = find(array(
                            'table' => 'pick_order_detail as a join pick_order as b on a.orderId = b.id',
                            'field' => "a.*",
                            'where' => "b.state = '已确认' and b.type=0 and a.sourceId = '$detail[id]' "
                        ));
                        $sendNum = 0;
                        foreach ($sendAll['array'] as $send) {
                            $sendNum += machiningOrderClass::material_num_change($send['materialId'], $send['unit'], $material['unit'], $send['num']);
                        }
                        if ($needNum < self::formattingFigure($sendNum, 'numPrecision')) {
                            return "【" . materialClass::getName($array['materialId']) . "】的领料数量未满足计划单的需求数量";
                        }
                    }
                }
            }
        }
        return true;
    }

    /**
     * 确认
     */
    public function confirmEdit()
    {
        $id = $this->post('id');
        $info = query(self::table, " id = '$id'");
        $field = [
            'state' => '已确认',
            'checkId' => self::$stid,
            'confirmTime' => $this->time
        ];
        // 按生产计划单领料控制入库/质检
        $bool = $this->inCtrl($id);
        if (!$this->power(self::page, 'confirm')) {
            $json['warn'] = '你还没有确认权限';
        } elseif (empty($info['id'])) {
            $json['warn'] = '未找到此生产入库单';
        } elseif ($info['state'] != '待确认') {
            $json['warn'] = '此生产入库单不是待确认状态，不能确认';
        } elseif (static::total(array('table' => 'machining_in_order_detail', "where" => "orderId = '$info[id]' and coid = '" . self::$coid . "' and warehouseId = ''")) > 0) {
            $json['warn'] = '仓库为空，不能提交';
        } elseif (isset($_POST['password']) && verifyPwd($this->post('password'), self::$user['password']) === false) {
            $json['warn'] = '登录密码输入错误';
        } elseif ($bool !== true) {
            $json['warn'] = $bool;
        } else {
            $this->startTrans();
            $json['warn'] = update(array(
                "table" => self::table,
                "field" => $field,
                "where" => "id = '$info[id]'",
            ));
            //生成入库单和质检单
            $bool = $this->insertInventory($info);
            if (in_array($json['warn'], ["新增成功", "更新成功"]) && $bool === true) {
                $this->commitTrans();
                // 单据是否需要复核
                if(!in_array(self::page,self::$publicSettings['documentReview'])) {
                    self::insertOperateLog($info['id'],self::title,"提交、复核");
                }else{
                    self::insertOperateLog($info['id'],self::title,"复核");
                }
                //添加日志
                $type = mb_substr($json['warn'], 0, 2, 'utf-8');
                $text = $this->control['name'] . $type . "了" . self::title . "id：【" . $id . '】';
                $this->logText(["type" => self::page, "text" => $text]);
                //返回
                $_SESSION['warn'] = $json['warn'];
                $json['warn'] = 2;
                $json['href'] = root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=detail&id=" . $info['id'];
            } else {
                $json['warn'] = $json['warn'] == '更新成功' ? $bool : $json['warn'];
                $this->rollback();
            }
        }
        resp:
        return json_encode($json, 320);
    }

    /**
     * 撤回
     */
    public function cancelEdit()
    {
        $id = $this->post('id');
        $info = query(self::table, " id = '$id'");
        $field = [
            'state' => '草稿',
            'checkId' => '',
            'confirmTime' => ''
        ];
        if (!$this->power(self::page, 'cancel')) {
            $json['warn'] = '你还没有撤回权限';
        } elseif (empty($info['id'])) {
            $json['warn'] = '未找到此生产入库单';
        } elseif ($info['state'] != '已确认') {
            $json['warn'] = '此生产入库单不是已确认状态，无需撤回';
        } elseif (static::total(array('table' => 'inventory', "where" => "sourceId = '$info[id]' and coid = '" . self::$coid . "' and state in ('部分入库','已入库')")) > 0) {
            $json['warn'] = '此生产入库单已存在有入库的单据，不能撤回';
        } elseif (static::total(array('table' => 'quality_order', "where" => "sourceId = '$info[id]' and coid = '" . self::$coid . "' and state ='已质检'")) > 0) {
            $json['warn'] = '此生产入库单已存在有已质检的单据，不能撤回';
        } else {
            $json['warn'] = update(array(
                "table" => self::table,
                "field" => $field,
                "where" => "id = '$info[id]'",
            ));
            if (in_array($json['warn'], ["新增成功", "更新成功"])) {
                //删除出库单
                delete(array('table' => 'inventory_detail', 'where' => "orderId in (select id from inventory where sourceId = '$info[id]' and coid = '" . self::$coid . "')"));
                delete(array('table' => 'inventory', 'where' => "sourceId = '$info[id]'"));
                //删除质检单
                delete(array('table' => 'quality_order_item', 'where' => "orderId in (select id from quality_order where sourceId = '$info[id]' and coid = '" . self::$coid . "')"));
                delete(array('table' => 'quality_order_reason', 'where' => "orderId in (select id from quality_order where sourceId = '$info[id]' and coid = '" . self::$coid . "')"));
                delete(array('table' => 'quality_order', 'where' => "sourceId = '$info[id]'"));
                self::insertOperateLog($info['id'],self::title,"撤回");
                //添加日志
                $type = mb_substr($json['warn'], 0, 2, 'utf-8');
                $text = $this->control['name'] . $type . "了" . self::title . "id：【" . $id . '】';
                $this->logText(["type" => self::page, "text" => $text]);
                //返回
                $_SESSION['warn'] = $json['warn'];
                $json['warn'] = 2;
                $json['href'] = root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=detail&id=" . $info['id'];
            }
        }
        resp:
        return json_encode($json, 320);
    }
    /**
     * Desc : 提交前数据验证
     * User : you name
     * Date : 2023-11-17 16:04
     * @param $info
     * @return string|bool
     */
    public function dataValidation($info): string|bool
    {
        $annotation = [
            'lineId' => '生产线',
            'manager' => '经手人',
            'recordDate' => '单据日期',
        ];
        $rules = [
            'lineId' => 'required',
            'manager' => 'required',
            'recordDate' => 'required|date',
        ];
        // 校验是否符合规则
        $vt = new \verify();
        $result = $vt->setAliases($annotation)->validate($info, $rules)->isOk();
        if ($result === false) {
            return $vt->getErrs()[0];  // 多个规则提示最前面一条
        }
        $result = find(array('table' => self::tableMx, 'field' => 'id,materialId,num,unit,warehouseId', 'where' => "orderId = '$info[id]' order by list"));
        if(count($result['array']) == 0){
            return "请完善入库明细";
        }
        if(static::is_null_array(array_column($result['array'],'materialId'))){
            return "入库明细中物料不能为空";
        }
        if(static::is_null_array(array_column($result['array'],'unit'))){
            return "入库明细中物料不能为空";
        }
        if(static::is_null_array(array_column($result['array'],'warehouseId'))){
            return "入库明细中【仓库】不能为空";
        }
        if(static::is_null_array(array_column($result['array'],'num'),false)){
            return "入库明细中【数量】不能为空，且必须大于0";
        }

        return true;
    }
    /**
     * 提交
     */
    public function commitEdit()
    {
        $id = $this->post('id');
        $info = query(self::table, " id = '$id'");
        $field = [
            'state' => '待确认',
        ];
        //提交前数据验证
        $json['warn'] = $this->dataValidation($info);
        if($json['warn'] !== true){
            goto resp;
        }
        if (!$this->power(self::page, 'edit')) {
            $json['warn'] = '你还没有编辑权限';
        } elseif (empty($info['id'])) {
            $json['warn'] = '未找到此生产入库单';
        } elseif ($info['state'] != '草稿') {
            $json['warn'] = '此生产入库单不是草稿状态，不能提交';
        } elseif (static::total(array('table' => 'machining_in_order_detail', "where" => "orderId = '$info[id]' and coid = '" . self::$coid . "' and warehouseId = ''")) > 0) {
            $json['warn'] = '仓库为空，不能提交';
        } else {
            $this->startTrans();
            $json['warn'] = update(array(
                "table" => self::table,
                "field" => $field,
                "where" => "id = '$info[id]'",
            ));

            $all = find(array('table' => self::tableMx, 'where' => "orderId = '$info[id]' order by time asc"));
            foreach ($all['array'] as $array) {
//                $machining_order_mx = query('machining_order_mx',"id = '$array[sourceId]'");
//                if(static::total(array('table'=>'inventory_detail as a join inventory as b on a.orderId = b.id','where'=>"b.coid = '".self::$coid."' and b.state = '已出库' and a.sourceId in (select id from pick_order_detail where sourceId in (select id from machining_order_detail where orderId = '$machining_order_mx[orderId]' ))")) ==0){
//                    //判断是否有领料单出库
//                    $machining_order = query('machining_order',"id = '$machining_order_mx[orderId]'");
//                    $json['warn'] =  "生产计划单【{$machining_order['orderNo']}】还未领料出库";
//                    break;
//                }
                $material = query('material', "id = '$array[materialId]'");
                if ($material['IPQC']) {
                    $allTypeId = explode('/',$material['typePath']);
                    //查找质检方案
                    $quarantine = query(
                        'quarantine',
                        "application like '%制终检验%' and coid = '" . self::$coid . "' and state = '启用' and startDate<= date_format(now(),'%Y-%m-%d') and endDate>date_format(now(),'%Y-%m-%d')  and if(materialId,materialId = '$material[id]',materialTypeId in ('" . implode("','", $allTypeId) . "')) order by materialId desc,list desc,time desc"
                    );
                    if (empty($quarantine['id'])) {
                        $json['warn'] = "未找到产品【{$material['name']}】的质检方案";
                        break;
                    }
                }
            }
            if (in_array($json['warn'], ["新增成功", "更新成功"])) {
                // 单据是否需要复核
                if(!in_array(self::page,self::$publicSettings['documentReview'])){
                    $resultJson = $this->confirmEdit();
                    $json = json_decode($resultJson,true);
                    if ($json['warn'] != 2){
                        $this->rollback();
                        goto resp;
                    }
                }else {
                    self::insertOperateLog($info['id'],self::title,"提交");
                }
                $this->commitTrans();
                //添加日志
                $type = mb_substr($json['warn'], 0, 2, 'utf-8');
                $text = $this->control['name'] . $type . "了" . self::title . "id：【" . $id . '】';
                $this->logText(["type" => self::page, "text" => $text]);
                //返回
                $_SESSION['warn'] = $json['warn'];
                $json['warn'] = 2;
                $json['href'] = root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=detail&id=" . $info['id'];
            } else {
                $this->rollback();
            }
        }
        resp:
        return json_encode($json, 320);
    }

    /**
     * 生成出库单(需要生成质检单)
     */
    public function insertInventory($info, $isRoll = true): bool|string
    {
        $bool = true;
        $quality = [];//质检分组
        $re_array = [];//根据仓库重新分组
        $result = find(array('table' => self::tableMx, 'where' => "orderId = '$info[id]' order by list asc"));
        foreach ($result['array'] as $array) {
            $material = query('material', "id = '$array[materialId]'");
            if ($material['IPQC']) {
                //质检
                $quality[$array['materialId']][$array['id']] = ['num' => $array['num']];
            }
            //入库
            $re_array[$array['warehouseId']][] = $array['id'];
        }
        $inventory_to_quality = [];//把库存ID插入质检单中
        $index = 1;
        $line = query('product_line',"id = '$info[lineId]'");
        //入库
        foreach ($re_array as $warehouseId => $array) {
            $id = self::getId();
            $field = [
                'id' => $id,
                'type' => '生产入库',
                'coid' => self::$coid,
                'sourceTable' => self::table,
                'sourceId' => $info['id'],
                'warehouseId' => $warehouseId,
                'targetId' => $info['lineId'],
                'classify' => 1,
                'state' => '待入库',
                'workFlow' => !empty($quality) ? '待质检' : '已质检',
                'stid' => self::$stid,
                'orderDate' => $this->date,
                'sourceDate' => $info['recordDate'],
                'sourceNo' => $info['orderNo'],
                'sourceTargetName' =>$line['workshop'].$line['name']
            ];
            $userNo = codeTemplateClass::generateCode('inStock', [
                'prefix' => 'KCRK' . date('Ymd'),
                'table' => 'inventory',
                'field' => 'orderNo',
                'where' => " and coid = '" . self::$coid . "'",
                'index' => $index
            ], $field);
            $index = $isRoll ? $index + 1 : $index;
            $field['orderNo'] = $userNo;
            $warn = static::insert(array(
                'table' => 'inventory',
                'field' => $field
            ));
            if ($warn != '新增成功') {
                return "新增入库单失败";
            }
            foreach ($array as $mxId) {
                $mx = query(self::tableMx, "id = '$mxId'");
                $inventory_to_quality[$mxId] = $id;
                $price = inventoryDefaultClass::pricingRules('inStockPrice', $mx['materialId'], $mx['unit']);
                $warn = static::insert(array(
                    'table' => 'inventory_detail',
                    'field' => [
                        'id' => self::getId(),
                        'coid' => self::$coid,
                        'sourceTable' => self::tableMx,
                        'sourceId' => $mx['id'],
                        'materialId' => $mx['materialId'],
                        'warehouseId' => $warehouseId,
                        'unit' => $mx['unit'],
                        'orderId' => $id,
                        'orderNum' => $mx['num'],
                        'price' => $price,
                        'batch' => $mx['batch'],
                        'quality'       => isset($quality[$mx['materialId']][$mxId]) ? 1 : 0,
                        'pass_num'      => isset($quality[$mx['materialId']][$mxId]) ? 0 : $mx['num'],
                    ]
                ));
                if ($warn != '新增成功') {
                    return "新增入库单明细失败";
                }
            }
        }

        $index = 1;
        //质检
        foreach ($quality as $materialId => $array) {
            foreach ($array as $mxId => $item) {
                $mx = query(self::tableMx, "id = '$mxId'");
                $material = query('material', "id = '$materialId'");
                $allTypeId = explode('/',$material['typePath']);
                //查找质检方案
                $quarantine = query(
                    'quarantine',
                    "application like '%制终检验%' and state = '启用' and coid = '" . self::$coid . "' and startDate<= date_format(now(),'%Y-%m-%d') and endDate>date_format(now(),'%Y-%m-%d') and if(materialId !='',materialId = '$material[id]',materialTypeId in ('" . implode("','", $allTypeId) . "')) order by materialId desc,list desc,time desc"
                );
                if (empty($quarantine['id'])) {
                    return "未找到产品【{$material['name']}】的质检方案";
                }
                //根据质检批量分成几组
                $num = $quarantine['qualityBatch'] > 0 ? ceil($item['num'] / $quarantine['qualityBatch']) : 1;
                $userNo = codeTemplateClass::generateCode('processInspection', [
                    'prefix' => 'IP' . date('Ymd'),
                    'table' => 'quality_order',
                    'field' => 'orderNo',
                    'where' => " and coid = '" . self::$coid . "'",
                    'index' => $index
                ], []);
                $index++;
                if ($num > 100) {
                    return "质检批量过小，新增质检单数量超过100条";
                }
                for ($i = 1; $i <= $num; $i++) {
                    $id = self::getId();
                    $remindNum = ($item['num'] - ($i - 1) * $quarantine['qualityBatch']);
                    $warn = static::insert(array(
                        'table' => 'quality_order',
                        'field' => [
                            'id' => $id,
                            'type' => 2,
                            'coid' => self::$coid,
                            'sourceTable' => self::table,
                            'sourceId' => $info['id'],
                            'sourceMxId' => $mxId,
                            'targetId' => $info['lineId'],
                            'inventoryId' => $inventory_to_quality[$mx['id']] ?? '',
                            'warehouseId' => $mx['warehouseId'],
                            'num' => $remindNum > $quarantine['qualityBatch'] && $quarantine['qualityBatch'] > 0 ? $quarantine['qualityBatch'] : $remindNum,
                            'materialId' => $material['id'],
                            'unit' => $mx['unit'],
                            'orderNo' => $userNo,
                            'batch' => $userNo . '-' . $i,
                            'qid' => $quarantine['id'],
                            'sourceNo' => $info['orderNo'],
                            'state' => '待质检',
                        ]
                    ));
                    if ($warn != '新增成功') {
                        return "新增质检单失败";
                    }
                    $all = find(array('table' => 'quarantine_item', 'where' => "orderId = '$quarantine[id]' order by list"));
                    foreach ($all['array'] as $val) {
                        $warn = static::insert(array(
                            'table' => 'quality_order_item',
                            'field' => [
                                'id' => self::getId(),
                                'coid' => self::$coid,
                                'orderId' => $id,
                                'itemId' => $val['id'],
                            ]
                        ));
                        if ($warn != '新增成功') {
                            return "新增质检单明细质检项目失败";
                        }
                    }
                }
            }

        }
        return $bool;
    }

    /**
     * 获取当前分类ID的所有父级分类（包括自己）
     * @param $id
     * @return array
     */
    public static function getAllParentTypeId($id): array
    {
        $typeIdArr = [];
        if (empty($id)) {
            return $typeIdArr;
        } else {
            $typeIdArr[] = $id;
            $material_type = query('material_type', "id = '$id'");
            $parent = query('material_type', "id = '$material_type[pid]'");
            if (!empty($parent['id'])) {
                $result = self::getAllParentTypeId($parent['id']);
                $typeIdArr = array_merge($typeIdArr, $result);
            }
        }
        return array_filter($typeIdArr);
    }

    // 操作中转
    public function operate()
    {
        $act = $this->post('act');
        $pwd = $word = false; // 需要密码
        if ($this->post('pwd')) {
            $pwd = true;
        }
        $title = '';
        if ($this->post('title')) {
            $title = $this->post('title');
        }
        $form = $power = '';
        switch ($act) {
            case 'confirm':
                $act = 'confirm';
                $msg = '确认';
                $title = $title ?: '是否已确认此生产入库单，确认后将不可修改？';
                $function = 'confirmEdit';
                $form = self::page . 'OperateForm, detailForm';
                $power = '';
                $word = true;
                break;
            case 'commit':
                $act = 'edit';
                $msg = '编辑';
                $title = '是否确认提交此生产入库单？';
                $function = 'commitEdit';
                $form = self::page . 'OperateForm, detailForm';
                $power = '';
                $word = true;
                break;
            case 'cancel':
                $act = 'cancel';
                $msg = '撤回';
                $title = '是否确认撤回此生产入库单？';
                $function = 'cancelEdit';
                $form = self::page . 'OperateForm, detailForm';
                $power = '';
                $word = true;
                break;
            default:
                $act = 'del';
                $msg = '删除' . self::title;
                $title = self::page . 'Delete';
                $function = 'delete';
                $form = self::page . 'OperateForm, listForm, quoForm';
                $power = '';
                break;
        }
        if (!$this->power(self::page, $act)) {
            $_SESSION['warn'] = '你还没有' . $msg . '的权限';
            $json = [
                'warn' => 2,
                'href' => root . 'control/adIndex.html?cla=' . $this->get('cla') . '&fun=home',
            ];
        } else {
            return $this->confirm([
                'title' => $title,
                'function' => $function,
                'form' => $form,
                'power' => $power,
                'pwd' => $pwd,
                'word' => $word
            ]);
        }

        resp:
        return json_encode($json, 320);
    }

    /**
     * 删除
     * @return bool|string
     */
    public function delete()
    {
        $array = $this->post('listId') ?? $this->post('id');
        if (!$this->power(self::page, "del")) {
            $json['warn'] = "你没有删除的权限";
        } elseif (empty($array)) {
            $json['warn'] = "你一个数据都没有选择呢";
        } else {
            $text = "";
            $x = 0;
            $array = is_array($array) ? $array : [$array];
            foreach ($array as $id) {
                $info = query(self::table, " id = '$id' ");
                if ($info['state'] == '已确认') {
                    $warn = "删除失败：已确认，暂不能删除";
                } else {
                    //最后删除基本参数
                    delete(array("table" => self::table, "where" => " id = '$id' "));
                    delete(array("table" => self::tableMx, "where" => " orderId = '$id' "));
                    delete(array("table" => "auditing_follow", "where" => " typeId = '$id' "));
                    //返回
                    $warn = "删除成功";
                    $x++;
                }
                $text .= self::title . "ID【" . $info['id'] . "】" . $warn . "。<br>";
            }
            //添加日志
            $text = $this->control['name'] . "删除了" . self::title . "，结果如下：<br>" . $text;
            $this->logText(array("type" => self::page, "text" => $text));
            $_SESSION['warn'] = "删除了" . $x . "个" . self::title . "，详情见系统日志。";
            $json['warn'] = 2;
            $json['href'] = root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=home";
        }
        return json_encode($json, 320);
    }

}
